package com.tfkj.contrller;
import com.tfkj.entity.*;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.*;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SDKGlobalConfiguration;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.tfkj.Config;
import com.tfkj.service.AllService;
import com.tfkj.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static com.tfkj.Config.*;
import static com.tfkj.contrller.PdfUtil.*;

@RestController
@CrossOrigin(maxAge = 3600)
@RequestMapping("/question")
@Api(value = "题库", tags = "题库接口")
public class QuestionController {

    @Autowired
    private AllService allService;

    @Autowired
    private Config config;

    @ApiOperation("查询题库-by类型编码、难度")
    @PostMapping("/list")
    public CommonReturn getQuestions(@RequestBody QuestionQueryVO vo) {
        List<Question> qs = new ArrayList<>();
        Integer total = 0;
        if (vo.getIsSelect() == 0) {
            qs = allService.findQuestionWithSubject(vo.getGrade(), vo.getSubject(), vo.getPageNum(), vo.getPageSize());
            total = allService.findQuestionWithSubjectTotal(vo.getGrade(), vo.getSubject());
        } else {
            qs = allService.findQuestion(vo.getGrade(), vo.getSubject(), vo.getQuestionType(), vo.getDifficulty(), vo.getPageNum(), vo.getPageSize());
            total = allService.findQuestionTotal(vo.getGrade(), vo.getSubject(), vo.getQuestionType(), vo.getDifficulty());
        }
        return new CommonReturn(qs, total);
    }


    @ApiOperation("查询题库-by类型编码、难度")
    @GetMapping("/list/random")
    public CommonReturn getQuestionsRandom(@RequestParam("grade") String grade,@RequestParam("subject") String subject,@RequestParam("questionType") String questionType, @RequestParam("difficulty")Integer difficulty) {
        List<Question> qs = allService.findQuestionRandom(grade, subject, questionType,difficulty);
        return new CommonReturn(qs);
    }


    @ApiOperation("补充题目类型和难度")
    @PostMapping("/update")
    public CommonReturn updateImage(@RequestBody UpdateImageVO vo) {
        Integer i = allService.updateQuestion(vo.getId(), vo.getGrade(), vo.getSubject(), vo.getQuestionType(), vo.getDifficulty());
        System.out.println("修改行数："+ i);
        return new CommonReturn(200, "更新成功！");
    }


    @ApiOperation("教师推荐题目")
    @PostMapping("/suggestion")
    public CommonReturn suggestion(@RequestBody Suggestion vo) {
        if (vo.getClassName() != null && "".equals(vo.getClassName())){
            String studentIds = allService.findStudentIds(vo.getClassName());
            if ("".equals(studentIds)) {
                return new CommonReturn(200, "推荐成功！");
            }
            vo.setStudentIds(studentIds);
        }
        allService.suggestion(vo.getTeacherNum(), vo.getQuestionIds().replace('，',','), vo.getStudentIds());
        return new CommonReturn(200, "推荐成功！");
    }


    @ApiOperation("学生查看老师推荐题目")
    @GetMapping("/suggestionList")
    public CommonReturn suggestionList(@RequestParam(value = "studentNum",required = true) String studentNum, @RequestParam("teacherNum") String teacherNum, @RequestParam(value = "crateDate" ,required = false) LocalDate crateDate) {
        List<QuestionSuggestionVO> list = allService.suggestionSearch(studentNum, teacherNum, crateDate);
        return new CommonReturn(list);
    }

    @ApiOperation("查询题库类型")
    @GetMapping("/typeList")
    public CommonReturn getQuestionType() {
        List<QuestionType> qs = allService.findQuestionType();
        if (qs != null) {
            return new CommonReturn(TreeBuilder.buildTree(qs));
        } else {
            return new CommonReturn(new ArrayList<>());
        }
    }


    @ApiOperation("查询年级")
    @GetMapping("/gradeList")
    public CommonReturn getGrade() {
        List<String> qs = allService.findGrade();
        return new CommonReturn(qs);
    }


    @ApiOperation("查询年级")
    @GetMapping("/subjectList")
    public CommonReturn getSubject(@RequestParam("grade") String grade) {
        List<String> qs = allService.findSubject(grade);
        return new CommonReturn(qs);
    }


    @ApiOperation("查询类型")
    @GetMapping("/questionTypeList")
    public CommonReturn getSubject(@RequestParam(value = "grade", required = false) String grade, @RequestParam(value = "subject", required = false) String subject) {
        List<QuestionType> qs = allService.findQuestionType(grade, subject);
        return new CommonReturn(qs);
    }

    @ApiOperation("查询题库类型枚举值")
    @GetMapping("/typeEnumeration")
    public CommonReturn getQuestionTypeEnumeration () {
        QuestionEnumerationVO qe = allService.findQuestiontypeEnumeration();
        return new CommonReturn(qe);
    }
    @ApiOperation("查询题库类型枚举值")
    @GetMapping("/allTypeList")
    public CommonReturn questionList () {
        List<QuestionType> list = allService.findQuestionType();
        Map<Integer, String> map = new HashMap<>();
        for (QuestionType qt : list) {
            map.put(qt.getId(), qt.getGrade()+"-"+qt.getSubject()+"-"+qt.getQuestionType());
        }
        return new CommonReturn(map);
    }
    @ApiOperation("删除题库")
    @PostMapping("/delete/{id}")
    public CommonReturn deleteQuestion(@PathVariable("id") Integer id) {
        allService.deleteQuestion(id);
        return new CommonReturn(200, "删除测验成功！");
    }
    @ApiOperation("删除题库类型")
    @PostMapping("/deleteType/{id}")
    public CommonReturn deleteQuestionType(@PathVariable("id") Integer id) {
        allService.deleteQuestionType(id);
        return new CommonReturn(200, "删除类型成功！");
    }
    @ApiOperation("创建题库类型")
    @PostMapping("/createType")
    public CommonReturn createQuestionType(@RequestBody QuestionType questionType) {
        allService.createQuestionType(questionType);
        return new CommonReturn(200, "创建类型成功！");
    }
//
//    @ApiOperation("上传题至题库")
//    @PostMapping("/upload")
//    public CommonReturn handleFileUpload(@RequestParam("file") MultipartFile file, @RequestParam("typeId") Integer typeId, @RequestParam("difficulty") Integer difficulty) {
//        if (file.isEmpty()) {
//            return new CommonReturn(500, "空文件");
//        }
//        String url = Config.url;
//        try {
//            System.out.println("文件:"+file.getOriginalFilename());
//            Configuration cfg = new Configuration(Region.region2());
//            cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;// 指定分片上传版本
//            UploadManager uploadManager = new UploadManager(cfg);
//            String key = new Date().getTime() + file.getOriginalFilename();
//            Auth auth = Auth.create(accessKey, secretKey);
//            String upToken = auth.uploadToken(bucket);
//            try {
//                Response response = uploadManager.put(file.getBytes(), key, upToken);
//                //解析上传成功的结果
//                DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
//                url = url + putRet.key;
//            } catch (QiniuException ex) {
//                ex.printStackTrace();
//                if (ex.response != null) {
//                    System.err.println(ex.response);
//                    try {
//                        String body = ex.response.toString();
//                        System.err.println(body);
//                    } catch (Exception ignored) {
//                    }
//                }
//            }
//            System.out.println("上传："+url);
//            allService.createQuestion(typeId, url, difficulty);
//            return new CommonReturn(200, "上传成功！");
//
//        } catch (Exception e) {
//            System.out.println(e.getMessage());
//            return new CommonReturn(500, "上传失败！");
//        }
//    }


    @ApiOperation("框选题目保存到题库")
    @PostMapping("/makeQuestion")
    public CommonReturn makeQuestion(@RequestBody CreateImageListVO vos) throws Exception {
        Map<String, BufferedImage> urls = new HashMap<>();
        int index = 0;
        List<Question> questionList = new ArrayList<>();
        for (CreateImageVO vo : vos.getVos()){
            if (!urls.containsKey(vo.getUrl())){
                urls.put(vo.getUrl(), getImageFromURL(vo.getUrl()));
            }
            String[] ps = vo.getPosition().split(",");
            InputStreamDTO image = cropPDFPage(urls.get(vo.getUrl()), Integer.valueOf(ps[1]), Integer.valueOf(ps[3]), vo.getHeight());
            String preFileName = String.valueOf(new Date().getTime());
            String key = preFileName + "_" + index + ".png";
            index++;
            try {
                System.setProperty(SDKGlobalConfiguration.ENABLE_S3_SIGV4_SYSTEM_PROPERTY, "true");
                AmazonS3 s3 = config.amazonS3();
                ObjectMetadata objectMetadata = new ObjectMetadata();
                objectMetadata.setContentType("image/png");
                objectMetadata.setContentLength(image.getLength());
                //解析上传成功的结果
                s3.putObject(bucket, key, image.getInputStream(), objectMetadata);
                System.out.format("Uploading %s to S3 bucket %s...\n", key, bucket);
                Question question = new Question();
                question.setTestId(vos.getTestId());
                question.setUrl(url + key);
                question.setGrade(vos.getGrade());
                question.setSubject(vos.getSubject());
                System.out.println(question);
                questionList.add(question);
            } catch (AmazonServiceException e) {
                System.err.println(e.getErrorMessage());
                System.exit(1);
            }
        }
        allService.insertQuestions(questionList);
        return new CommonReturn(200, "上传成功！");
    }

    @ApiOperation("选择URL题目进行导出")
    @PostMapping("/exportUrls")
    public ResponseEntity<ByteArrayResource> makeQuestion(@RequestBody DownloadVO vo, HttpServletResponse response) throws Exception {
        List<String> urls;
        if (vo.getSuggestionNum() == null || 0 == vo.getSuggestionNum()) {
            urls = allService.findUrls(vo.getIds(), vo.getType());
        } else {
            urls = allService.findUrlsWithSuggestion(vo.getIds(), vo.getType(), vo.getSuggestionNum());
        }
        Set<String> set = new LinkedHashSet<>(urls);
        List<String> distinctList = new ArrayList<>(set);
        // 调用 createPdfWithImages 方法生成 PDF 的字节数组输出流
        ByteArrayOutputStream pdfOutputStream = createPdfWithImages(distinctList, vo.getGrade(), vo.getClassName(), vo.getStudentNum(), vo.getName(), vo.getRole());

        // 将字节数组输出流转换为字节数组
        byte[] pdfBytes = pdfOutputStream.toByteArray();

        // 创建 ByteArrayResource 以便将字节数组作为资源返回
        ByteArrayResource resource = new ByteArrayResource(pdfBytes);

        // 设置 HTTP 响应头
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=images.pdf");
        headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_PDF_VALUE);

        // 返回 ResponseEntity，包含 PDF 资源和响应头
        return ResponseEntity.ok()
                .headers(headers)
                .contentLength(pdfBytes.length)
                .contentType(MediaType.APPLICATION_PDF)
                .body(resource);
    }

    @ApiOperation("选择URL题目进行导出-教师专用")
    @PostMapping("/exportZip")
    public Object makeQuestion (
            @RequestBody DownloadForTeacherVO vo,
            HttpServletResponse response) throws Exception {
        List<Student> users = new ArrayList<>();

        if (vo.getClassName() != null && !"".equals(vo.getClassName())) {
            users = allService.findAllUser("学生",vo.getClassName(), null, 1, 1000);
        } else {
            users = allService.findAllUser(vo.getStudentNum());
        }
        if (users.isEmpty()){
            return new CommonReturn(500, "空数据下载");
        }
        Map<String, DownloadZipMapVO> studentMap = new HashMap<>();
        String findUrlStudentStr;
        if (vo.getStudentNum() != null && !"".equals(vo.getStudentNum())) {
            findUrlStudentStr = vo.getStudentNum();
        } else {
            findUrlStudentStr = users.stream()
                    .map(Student::getStudentNum)
                    .collect(Collectors.joining(","));
        }
        List<RelAndImageVO> images = new ArrayList<>();
        if ("question".equals(vo.getType())) {
            images = allService.findSuggestions(findUrlStudentStr, vo.getStartDate(), vo.getEndDate());
        } else {
            images = allService.findImages(findUrlStudentStr, vo.getStartDate(), vo.getEndDate());
        }

        if (images.isEmpty()) {
            return new CommonReturn(500, "空数据下载");
        }
        Map<String, CompletableFuture<BufferedImage>> futures = images.stream()
                .map(RelAndImageVO::getUrl)
                .distinct()
                .collect(Collectors.toMap(
                        url -> url,
                        url -> CompletableFuture.supplyAsync(() -> {
                            try {
                                return ImageIO.read(new URL(url));
                            } catch (IOException e) {
                                return null;
                            }
                        })
                ));
        Map<String, List<String>> imageStudentNumMap = images.stream()
                .collect(Collectors.groupingBy(
                        RelAndImageVO::getStudentNum,
                        Collectors.mapping(RelAndImageVO::getUrl, Collectors.toList())
                ));
        // 等待所有异步任务完成
        Map<String, BufferedImage> imageMap = futures.entrySet().stream()
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        entry -> {
                            try {
                                return entry.getValue().get();
                            } catch (InterruptedException | ExecutionException e) {
                                return null;
                            }
                        }
                ))
                .entrySet().stream()
                .filter(entry -> entry.getValue() != null)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        // 创建ZIP容器
        ByteArrayOutputStream zipBaos = new ByteArrayOutputStream();
        try (ZipOutputStream zos = new ZipOutputStream(zipBaos)) {
        for (Student student : users) {
            if (imageStudentNumMap.get(student.getStudentNum()) == null || imageStudentNumMap.get(student.getStudentNum()).isEmpty()) {
                continue;
            }
            ByteArrayOutputStream pdfOutputStream = createPdfWithImages(imageMap, imageStudentNumMap.get(student.getStudentNum()), student.getGrade(), student.getClassName(), student.getStudentNum(), student.getName());
            // 构建ZIP条目
            String fileName = student.getStudentNum() + "-" + student.getName() + ".pdf";
            zos.putNextEntry(new ZipEntry(fileName));
            zos.write(pdfOutputStream.toByteArray());
            zos.closeEntry();
        }
        }

        // 步骤1：获取字节数组
        byte[] byteArray = zipBaos.toByteArray();

        // 步骤2：创建目标文件对象
        File file = new File("output.zip");

        // 步骤3：写入文件
        try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
            fileOutputStream.write(byteArray);
            System.out.println("文件已生成：" + file.getAbsolutePath());
        } catch (IOException e) {
            e.printStackTrace();
        }
        InputStreamResource resource = new InputStreamResource(new FileInputStream(file));

        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + file.getName());
        headers.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream");

        return ResponseEntity.ok()
                .headers(headers)
                .contentLength(file.length())
                .body(resource);
    }

    private ByteArrayOutputStream createPdfWithImages(List<String> imageUrls, String grade, String className, String studentNum, String name, String role) throws IOException {
        // 创建一个字节数组输出流来存储PDF内容
        ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();

        // 创建PDDocument实例
        try (PDDocument document = new PDDocument()) {
            // 设置页面大小为A4
            PDRectangle pageSize = PDRectangle.A4;
            float pageWidth = pageSize.getWidth();
            float pageHeight = pageSize.getHeight();
            float currentY = 0; // 记录当前页面上已绘制的图片的最底部位置
            float x = 0; // 初始化 x 坐标，从左边界开始，考虑 10 像素的左边距
            float y = pageHeight - 10; // 初始化 y 坐标，从页面顶部开始，考虑 10 像素的上边距
            float imageMargin = 5; // 图片之间的间隔为 10
            // 像素

            // 遍历图片URL列表
            for (String imageUrl : imageUrls) {
                // 加载图片
                BufferedImage bufferedImage = ImageIO.read(new URL(imageUrl));
                if (bufferedImage == null) {
                    throw new IOException("Failed to load image from URL: " + imageUrl);
                }

                // 将BufferedImage转换为byte[]
                ByteArrayOutputStream imageOutputStream = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage, "jpg", imageOutputStream);
                byte[] imageBytes = imageOutputStream.toByteArray();
                imageOutputStream.close();

                // 将byte[]转换为PDImageXObject
                PDImageXObject pdImage = PDImageXObject.createFromByteArray(document, imageBytes, "image");

                // 获取图片的尺寸
                float imageWidth = pdImage.getWidth();
                float imageHeight = pdImage.getHeight();
                float scale = pageWidth / imageWidth; // 考虑间隔 10 像素，计算缩放比例
                float scaledImageWidth = imageWidth * scale;
                float scaledImageHeight = imageHeight * scale;

                // 检查是否需要新页面或换行
                if (y - (scaledImageHeight + imageMargin) < 0) { // 检查是否超出页面底部
                    // 创建一个新的页面
                    PDPage page = new PDPage(pageSize);
                    document.addPage(page);
                    x = 0; // 重置 x 坐标
                    y = pageHeight - 5; // 重置 y 坐标
                }
                if (x + scaledImageWidth + imageMargin > pageWidth) { // 检查是否超出页面右边界
                    x = 0; // 换行，重置 x 坐标
                    y -= (scaledImageHeight + imageMargin); // 换行，更新 y 坐标
                }

                // 获取当前页面
                PDPage page;
                if (document.getNumberOfPages() != 0) {
                    page = document.getPage(document.getNumberOfPages() - 1);
                } else {
                    // 如果还没有页面，先添加一个页面
                    page = new PDPage(pageSize);
                    document.addPage(page);
                    y = pageHeight - scaledImageHeight - 25F;//预留学号这一行
                    // 在此处添加在页面顶部居中添加一段文字的操作
                    if (studentNum != null && !"".equals(studentNum)) {
                        try (PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, false)) {
                            String str;
                            if ("学生".equals(role)){
                                str = "年级：" + grade + "  班级：" + className + "  姓名：" + name + " 学号：" + studentNum;
                            } else {
                                str = "年级：" + grade + "  班级：" + className + " 编号：" + studentNum;
                            }
                            // 计算文字宽度
                            float titleWidth = 12 * str.length();
                            // 计算居中位置的 x 坐标
                            float titleX = (pageWidth - titleWidth) / 2;
                            // 设置字体
                            PDFont font = PDType0Font.load(document, this.getClass().getResourceAsStream("/HanYiYanKaiW-2.ttf"));
                            contentStream.setFont(font, 12);
                            // 在页面顶部居中位置添加文字
                            contentStream.beginText();
                            contentStream.newLineAtOffset(titleX, pageHeight - 20F);
                            contentStream.showText(str);
                            contentStream.endText();
                        }
                    }
                }

                // 创建内容流
                try (PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, false)) {

                    // 绘制图片
                    contentStream.drawImage(pdImage, x, y, scaledImageWidth, scaledImageHeight);
                }

                // 更新当前页面上已绘制的图片的最底部位置
                y -= 5;
            }

            // 将文档保存到字节数组输出流
            document.save(pdfOutputStream);
        }

        // 返回PDF的字节码
        return pdfOutputStream;
    }

    private ByteArrayOutputStream createPdfWithImages(Map<String, BufferedImage> imageMap, List<String> imageUrls, String grade, String className, String studentNum, String name) throws IOException {
        // 创建一个字节数组输出流来存储PDF内容
        ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();

        // 创建PDDocument实例
        try (PDDocument document = new PDDocument()) {
            // 设置页面大小为A4
            PDRectangle pageSize = PDRectangle.A4;
            float pageWidth = pageSize.getWidth();
            float pageHeight = pageSize.getHeight();
            float currentY = 0; // 记录当前页面上已绘制的图片的最底部位置
            float x = 0; // 初始化 x 坐标，从左边界开始，考虑 10 像素的左边距
            float y = pageHeight - 10; // 初始化 y 坐标，从页面顶部开始，考虑 10 像素的上边距
            float imageMargin = 5; // 图片之间的间隔为 10
            // 像素

            // 遍历图片URL列表
            for (String url : imageUrls) {
                BufferedImage bufferedImage = imageMap.get(url);
                // 将BufferedImage转换为byte[]
                ByteArrayOutputStream imageOutputStream = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage, "jpg", imageOutputStream);
                byte[] imageBytes = imageOutputStream.toByteArray();
                imageOutputStream.close();

                // 将byte[]转换为PDImageXObject
                PDImageXObject pdImage = PDImageXObject.createFromByteArray(document, imageBytes, "image");

                // 获取图片的尺寸
                float imageWidth = pdImage.getWidth();
                float imageHeight = pdImage.getHeight();
                float scale = pageWidth / imageWidth; // 考虑间隔 10 像素，计算缩放比例
                float scaledImageWidth = imageWidth * scale;
                float scaledImageHeight = imageHeight * scale;

                // 检查是否需要新页面或换行
                if (y - (scaledImageHeight + imageMargin) < 0) { // 检查是否超出页面底部
                    // 创建一个新的页面
                    PDPage page = new PDPage(pageSize);
                    document.addPage(page);
                    x = 0; // 重置 x 坐标
                    y = pageHeight - 5; // 重置 y 坐标
                }
                if (x + scaledImageWidth + imageMargin > pageWidth) { // 检查是否超出页面右边界
                    x = 0; // 换行，重置 x 坐标
                    y -= (scaledImageHeight + imageMargin); // 换行，更新 y 坐标
                }

                // 获取当前页面
                PDPage page;
                if (document.getNumberOfPages() != 0) {
                    page = document.getPage(document.getNumberOfPages() - 1);
                } else {
                    // 如果还没有页面，先添加一个页面
                    page = new PDPage(pageSize);
                    document.addPage(page);
                    y = pageHeight - scaledImageHeight - 25F;//预留学号这一行
                    // 在此处添加在页面顶部居中添加一段文字的操作
                    if (studentNum != null && !"".equals(studentNum)) {
                        try (PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, false)) {
                            String str;
                            str = "年级：" + grade + "  班级：" + className + "  姓名：" + name + " 学号：" + studentNum;
                            // 计算文字宽度
                            float titleWidth = 12 * str.length();
                            // 计算居中位置的 x 坐标
                            float titleX = (pageWidth - titleWidth) / 2;
                            // 设置字体
                            PDFont font = PDType0Font.load(document, this.getClass().getResourceAsStream("/HanYiYanKaiW-2.ttf"));
                            contentStream.setFont(font, 12);
                            // 在页面顶部居中位置添加文字
                            contentStream.beginText();
                            contentStream.newLineAtOffset(titleX, pageHeight - 20F);
                            contentStream.showText(str);
                            contentStream.endText();
                        }
                    }
                }

                // 创建内容流
                try (PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, false)) {

                    // 绘制图片
                    contentStream.drawImage(pdImage, x, y, scaledImageWidth, scaledImageHeight);
                }

                // 更新当前页面上已绘制的图片的最底部位置
                y -= 5;
            }

            // 将文档保存到字节数组输出流
            document.save(pdfOutputStream);
        }

        // 返回PDF的字节码
        return pdfOutputStream;
    }
}
